package cn.felord.spring.security.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreFilter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@RestController
@RequestMapping("/foo")
@Slf4j
public class FooController {

    @GetMapping("/test")
    public String test() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        log.info("current authentication: 【 {} 】", authentication);
        return "success";
    }

    @GetMapping("/test1")
    @PreAuthorize("hasAnyRole('ADMIN')")
    public String test1() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        log.info("current authentication: 【 {} 】", authentication);
        return "success";
    }

    @GetMapping("/test2")
    @PreAuthorize("hasAuthority('ROLE_ADMIN')")
    public String test2() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        log.info("current authentication: 【 {} 】", authentication);
        return "success";
    }

    @GetMapping("/test3")
    @PreAuthorize("isAnonymous()")
    public String test3() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        log.info("current authentication: 【 {} 】", authentication);
        return "success";
    }

    @GetMapping("/bar")
    @PreAuthorize("principal.username.startsWith('Felordcn')")
    public String self() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        log.info("current authentication: 【 {} 】", authentication);
        return "bar";
    }

    @GetMapping("/param/{id}")
    @PreAuthorize("#id.equals(principal.username)")
    public String param(@PathVariable String id) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        log.info("current authentication: 【 {} 】", authentication);
        return id;
    }

    @PostMapping("/prefilter")
    @PreFilter("hasRole('AD') or filterObject.startsWith('f')")
    public Collection<String> preFilter(@RequestBody Collection<String> ids) {
        return ids;
    }

    @PostMapping("/prefilter2")
    @PreFilter(value = "filterObject.startsWith('F')", filterTarget = "ids")
    public Collection<String> preFilter2(@RequestBody Collection<String> ids) {
        return ids;
    }

    @GetMapping("/postfilter")
    @PostFilter("hasRole('AD') or filterObject.startsWith('f')")
    public Collection<String> postfilter() {
        List<String> list = new ArrayList<>();
        list.add("Felordcn");
        list.add("felord");
        list.add("jetty");
        return list;
    }

    @GetMapping("/secure")
    @Secured({"ROLE_ADMIN1", "ROLE_APP2", "ROLE_POP"})
    public String secure() {
        return "success";
    }
}
